package com.CityHunter.Activity;



import java.util.ArrayList;
import java.util.List;

import com.CityHunter.MyTextView;
import com.CityHunter.R;
import com.CityHunter.R.drawable;
import com.CityHunter.R.id;
import com.CityHunter.R.layout;

import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.hardware.Camera;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class CityHunter extends Activity {
	private SurfaceView sv;
	private SurfaceHolder sh;
	private LocationManager lmgr;
	private SensorManager smgr;
	private List<Sensor> slist;
	private float orientation;
	private Location user, dest;
	private Camera camera;
	private LinearLayout ll;

	private MyTextView tv, tv2;
	private MySensorListener msl;
	private MyLocationListener mll;
	private String state, state2;
	private DrawOnTop1 mDraw;
	private Location location;
	private 	LocationManager locationManager;
	private String provider;
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
		setContentView(R.layout.main);
	

		String serviceName = Context.LOCATION_SERVICE;
		locationManager = (LocationManager) getSystemService(serviceName);
		// String provider = LocationManager.GPS_PROVIDER;

		Criteria criteria = new Criteria();
		criteria.setAccuracy(Criteria.ACCURACY_FINE);
		criteria.setAltitudeRequired(false);
		criteria.setBearingRequired(false);
		criteria.setCostAllowed(true);
		criteria.setPowerRequirement(Criteria.POWER_LOW);
		 provider = locationManager.getBestProvider(criteria, true);

		 location = locationManager.getLastKnownLocation(provider);
		ll = (LinearLayout) findViewById(R.id.ll);
		sv = (SurfaceView) findViewById(R.id.sv);
		sh = sv.getHolder();
		sh.addCallback(new MySHCallback());

		sh.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		dest = new Location(provider);
		//22.331727,114.206448
		dest.setLatitude(22.357061);
		dest.setLongitude(114.127908);
		tv = new MyTextView(this, 40, 20);

		tv.setTextSize(18);
		ll.addView(tv);

		lmgr = (LocationManager) getSystemService(LOCATION_SERVICE);
		mll = new MyLocationListener();

		smgr = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
		msl = new MySensorListener();
		slist = smgr.getSensorList(Sensor.TYPE_ORIENTATION);
		if (slist.size() == 0) {
			Toast.makeText(this, "No orientation sensor", Toast.LENGTH_SHORT)
					.show();
			finish();
		}
		orientation = (float) 0.0;
		updateWithNewLocation(location);
		locationManager
				.requestLocationUpdates(provider, 0, 0, locationListener);

		smgr.registerListener(msl, slist.get(0), SensorManager.SENSOR_DELAY_UI);
		mDraw = new DrawOnTop1(this, 0, 0);
		addContentView(mDraw, new LayoutParams(LayoutParams.WRAP_CONTENT,
				LayoutParams.WRAP_CONTENT));
	}
	
	public void onResume(){
		super.onResume();
		locationManager
				.requestLocationUpdates(provider, 0, 0, locationListener);
		smgr.registerListener(msl, slist.get(0), SensorManager.SENSOR_DELAY_UI);
		
		
	}

	class MySHCallback implements SurfaceHolder.Callback {
		public void surfaceCreated(SurfaceHolder holder) {

			camera = Camera.open();

			if (camera == null) {
				Toast.makeText(CityHunter.this, "camera is null",
						Toast.LENGTH_SHORT).show();
				finish();
			}

			try {
				camera.setPreviewDisplay(sh);
			} catch (Exception e) {
				Toast.makeText(CityHunter.this, e.toString(),
						Toast.LENGTH_SHORT).show();
				finish();
			}
		}

		public void surfaceDestroyed(SurfaceHolder surfaceholder) {
			camera.stopPreview();
			camera.release();
		}

		public void surfaceChanged(SurfaceHolder surfaceholder, int format,
				int w, int h) {
			camera.startPreview();

			Camera.Parameters parameters = camera.getParameters();
			parameters.set("rotation", "90");

			camera.setParameters(parameters);

		}
	}

	protected void onPause() {
		super.onPause();
		lmgr.removeUpdates(mll);
		smgr.unregisterListener(msl, slist.get(0));
	}

	private void adjustSpot() {
		if (user == null)
			return;
		Spot spot = AsiaSpot.getFrontSpot(orientation, user);
		if (spot != null)
			tv.setText(spot.name);
	}

	class MyLocationListener implements LocationListener {
		@Override
		public void onLocationChanged(Location location) {
			if (location == null)
				return;

			user = location;
			adjustSpot();
		}

		@Override
		public void onProviderDisabled(String provider) {
		}

		@Override
		public void onProviderEnabled(String provider) {
		}

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
		}
	}

	private void updateWithNewLocation(Location location) {

		if (location != null) {
			double lat = location.getLatitude();
			double lng = location.getLongitude();
			orientation = location.bearingTo(dest);
			if (orientation<0){
				orientation=360+orientation;
			}
			state = "Current position was changed";
		} else {
			state = "NO MESSAGE";
		}
		state += "NOW:" + String.valueOf(orientation) + "\n";
		tv.setText(state + state2);
	}

	class MySensorListener implements SensorEventListener {
		public void onSensorChanged(SensorEvent event) {
			int diff;
			if (event.sensor == slist.get(0)) {

				// state2="�ڦV��:"+String.valueOf(event.values[0]);
				if (orientation - event.values[0] < 10
						&& orientation - event.values[0] > -10) {
					state2 = "Position"
							+ String.valueOf(event.values[0]);
					diff = (int) (orientation - event.values[0]);
					mDraw.setY(diff*8);
				} else {
					state2 = "state2"
							+ String.valueOf(event.values[0]);
				diff = (int) (orientation - event.values[0]);
				mDraw.setY(diff*9);
				
				}
				tv.setText(state + state2);
			

			}
		}

		public void onAccuracyChanged(Sensor sensor, int accuracy) {
		}
	}

	private final LocationListener locationListener = new LocationListener() {
		public void onLocationChanged(Location location) {
			updateWithNewLocation(location);

		}

		public void onProviderDisabled(String provider) {

		}

		public void onProviderEnabled(String provider) {
		}

		public void onStatusChanged(String provider, int status, Bundle extras) {
		}
	};

}

class AsiaSpot {
	static ArrayList<Spot> spotlist;

	static void init() {
		spotlist = new ArrayList<Spot>();

		spotlist.add(new Spot(22.333908, 114.207357, new String("���L��")));

	}

	static Spot getFrontSpot(float orientation, Location user) {
		Location dest = new Location(user);
		float target;

		float mindist = Float.MAX_VALUE;
		int spotI = -1;

		for (int i = 0; i < spotlist.size(); i++) {
			dest.setLatitude(spotlist.get(i).latitude);
			dest.setLongitude(spotlist.get(i).longitude);
			target = user.bearingTo(dest);

			float degree = target - orientation;
			if (degree < 0.0)
				degree = degree + 360.0f;
			if (degree > 180.0)
				degree = 360.0f - degree;

			if (degree < 10.0) {
				float dist = user.distanceTo(dest);
				if (dist < mindist) {
					mindist = dist;
					spotI = i;
				}
			}
		}

		if (spotI == -1)
			return null;
		return spotlist.get(spotI);
	}
}

class Spot {

	Spot(double latitude, double longitude, String name) {
		this.latitude = latitude;
		this.longitude = longitude;
		this.name = name;
	}

	double latitude;
	double longitude;
	String name;
}

class DrawOnTop1 extends View {

	private float orgx,orgy,x, y;

	public DrawOnTop1(Context context, float x, float y) {
		super(context);
		this.x = x;
		this.y = y;
		orgx=240;
		orgy=140;
		// TODO Auto-generated constructor stub
	}

	public void setXY(float x, float y) {
		this.x = x;
		this.y = y;
	

	}

	public void setY(float y) {

		this.y = y;
		invalidate();
	}

	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		Paint mPaint = new Paint();
		mPaint.setColor(Color.BLUE);
		mPaint.setStyle(Paint.Style.FILL);
		RectF rect = new RectF(150, 200, 200, 250);
		rect = new RectF(250, 150, 200, 200);
		// rect.union(50, 50);
		// canvas.drawRect(rect, mPaint);

		// shape.draw(canvas);
		// canvas.draw(shape, mPaint);
		Bitmap bmp = BitmapFactory.decodeResource(getResources(),
				R.drawable.favb);
		// canvas.drawOval(rect, mPaint);
		Matrix matrix = new Matrix();
		matrix.setTranslate(orgx+x, orgy-y);
		canvas.drawBitmap(bmp, matrix, mPaint);
		rect = new RectF(260, 160, 210, 210);
		// canvas.drawOval(rect, mPaint);
		super.onDraw(canvas);
	}
}
